﻿using System;
using System.Text.RegularExpressions;

namespace CarolLib.Extension
{
    public static class StringExtension
    {
        private static readonly Regex WebUrlExpression = new Regex(@"(http|https)://(([\w-]+\.)+[\w-]+)(/[\w- ./?%&=]*)?", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex EmailExpression = new Regex(@"^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$", RegexOptions.Singleline | RegexOptions.Compiled);
        private static readonly Regex StripHTMLExpression = new Regex("<\\S[^><]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.CultureInvariant | RegexOptions.Compiled);

        private static readonly char[] IllegalUrlCharacters = new[] { ';', '/', '\\', '?', ':', '@', '&', '=', '+', '$', ',', '<', '>', '#', '%', '.', '!', '*', '\'', '"', '(', ')', '[', ']', '{', '}', '|', '^', '`', '~', '–', '‘', '’', '“', '”' };

        public static bool IsWebUrl(this string target)
        {
            return !string.IsNullOrEmpty(target) && WebUrlExpression.IsMatch(target);
        }

        public static string GetUrlDomain(this string url)
        {
            if (WebUrlExpression.IsMatch(url))
            {
                Match m = WebUrlExpression.Match(url);
                return (m.Groups[2].Value);
            }
            return null;
        }

        public static bool IsEmail(this string target)
        {
            return !string.IsNullOrEmpty(target) && EmailExpression.IsMatch(target);
        }

        public static string NullSafe(this string target)
        {
            return (target ?? string.Empty).Trim();
        }

        public static string StripHtml(this string target)
        {
            return StripHTMLExpression.Replace(target, string.Empty);
        }

        public static Guid ToGuid(this string target)
        {
            if ((!string.IsNullOrEmpty(target)) && (target.Trim().Length == 22))
            {
                string encoded = string.Concat(target.Trim().Replace("-", "+").Replace("_", "/"), "==");

                byte[] base64 = Convert.FromBase64String(encoded);

                return new Guid(base64);
            }

            return Guid.Empty;
        }

        public static T ToEnum<T>(this string target, T defaultValue) where T : IComparable, IFormattable
        {
            T convertedValue = defaultValue;

            if (!string.IsNullOrEmpty(target))
            {
                try
                {
                    convertedValue = (T)Enum.Parse(typeof(T), target.Trim(), true);
                }
                catch (ArgumentException)
                {
                }
            }

            return convertedValue;
        }

        public static string CleanQuoteTag(this string text)
        {
            if (string.IsNullOrEmpty(text))
                return text;

            RegexOptions options = RegexOptions.IgnoreCase;

            for (int i = 0; i < 20; i++)
                text = Regex.Replace(text, @"\[quote(?:\s*)user=""((.|\n)*?)""\]((.|\n)*?)\[/quote(\s*)\]", "", options);
            for (int i = 0; i < 20; i++)
                text = Regex.Replace(text, @"\[quote\]([^>]+?|.+?)\[\/quote\]", "", options);
            return text;
        }

        public static int TryToInt(this string text)
        {
            int i;
            int.TryParse(text, out i);
            return i;
        }

        public static DateTime TryToDatetime(this string text, DateTime defaultValue)
        {
            DateTime result;
            try
            {
                result = Convert.ToDateTime(text);
            }
            catch (Exception)
            {
                result = defaultValue;
            }
            return result;
        }
    }

}
